package com.taotaojs.util.date;

import com.taotaojs.exception.MyInnerException;

import java.util.Calendar;
import java.util.Date;

/**
 * 时间段工具类
 * <ol>
 * <li>获取某单位时间的最大最小值</li>
 * <li>获取包含某个时间的某单位时间段【byAIGetDate】</li>
 * <li>获取两个时间的月份差</li>
 * </ol>
 * @author TaoTaojs
 * @Date 2019年11月19日10:45:39
 * @关联类
 * @参考链接
 */
public class CalendarStateUtil {

	public static final int DATE = 1;
	public static final int WEEK = 2;
	public static final int MONTH = 3;
	public static final int YEAR = 4;

	CalendarStateUtil() {

	}

	/** 获取本小时0分 */
	public static Date getHourTimeStart(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/** 获取本小时59分 */
	public static Date getHourTimeStop(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/** 获取本分钟0秒 */
	public static Date getMinuteTimeStart(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	/** 获取本分钟第59秒 */
	public static Date getMinuteTimeStop(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 将（某天）时间设置为最大
	 * @param calendar
	 */
	private static void setMaxDate(Calendar calendar){
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
	}
	/**
	 * 将（某天）时间设置为最小
	 * @param calendar
	 */
	private static void setMinDate(Calendar calendar){
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
	}

	/** 当天0点 */
	public static Date getDateStart(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMinDate(calendar);
		return calendar.getTime();
	}
	/** 当天23:59:59 */
	public static Date getDateStop(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMaxDate(calendar);
		return calendar.getTime();
	}

	/** 本周第一天*/
	public static Date getWeekStart(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMinDate(calendar);
		int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		if(week == 0){
			week = 7;
		}
		calendar.add(Calendar.DATE, -week + 1);
		return calendar.getTime();
	}
	/** 本周最后一天 */
	public static Date getWeekStop(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMaxDate(calendar);
		int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		if(week == 0){
			week = 7;
		}
		calendar.add(Calendar.DATE, -week + 7);
		return calendar.getTime();
	}

	/** 本月第一天 */
	public static Date getMouseStart(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMinDate(calendar);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		return calendar.getTime();
	}
	/** 本月最后一天 */
	public static Date getMouseStop(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMaxDate(calendar);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		return calendar.getTime();
	}

	/** 本年第一天 */
	public static Date getYearStart(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMinDate(calendar);
		calendar.set(Calendar.DAY_OF_YEAR, 1);
		return calendar.getTime();
	}
	/** 本年最后一天 */
	public static Date getYearStop(Date date){
		Calendar calendar = CalendarUtil.getCalendar(date);
		setMaxDate(calendar);
		calendar.set(Calendar.DAY_OF_YEAR, calendar.getActualMaximum(Calendar.DAY_OF_YEAR));
		return calendar.getTime();
	}

	/**
	 * 根据model类型，获取获取当前时间的某个时间段
	 * @param date 时间段中包含的一个时间点
	 * @param model 具体参考静态属性
	 * @return
	 * @throws Exception
	 */
	public static Date[] byAiGetDate(Date date, int model) {
		if(model == DATE){
			return new Date[]{getDateStart(date), getDateStop(date)};
		}else if(model == MONTH){
			return new Date[]{getMouseStart(date), getMouseStop(date)};
		}else if(model == WEEK){
			return new Date[]{getWeekStart(date), getWeekStop(date)};
		}else if(model == YEAR){
			return new Date[]{getYearStart(date), getYearStop(date)};
		}else{
			throw new MyInnerException("参数不正确！请检查");
		}
	}

	/**
	 * 获取两个时间的月份差
	 * @param startData 开始时间
	 * @param stopData 结束时间
	 * @return 结束时间-开始时间 = 正数，开始时间小于结束时间，，负数，开始时间大于结束时间
	 */
	public static int getDifferMonth(Date startData, Date stopData){
		//固定的某个日期
		Calendar start  = Calendar.getInstance();
		//当前的日期
		Calendar stop = Calendar.getInstance();
		start.setTime(startData);
		stop.setTime(stopData);
		int result = (stop.get(Calendar.MONTH) - start.get(Calendar.MONTH));
		int month = (stop.get(Calendar.YEAR) - start .get(Calendar.YEAR))*12;
		return result + month;
	}

	/**
	 * 获取两个时间的月份差（已经绝对值了）
	 * @param afterData
	 * @param beforeData
	 * @return
	 */
	public static int getDifferMonthAbs(Date afterData, Date beforeData){
		return Math.abs(getDifferMonth(afterData, beforeData));
	}

}
